package flexunit.sosui
{
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.XMLSocket;	

	/**
	 * @author Wang Kang
	 */
	public class SosConnector
	{
		public static const PASSED:String = "Passed";		public static const FAILED:String = "Failed";		public static const RESULT:String = "Result";

		public function SosConnector( host:String = "localhost", port:uint = 4444 )
		{
			_isConnected = false;
			_host = host;
			_port = port;
			
			_buffer = new Array();
			_socket = new XMLSocket();
			_socket.addEventListener(Event.CONNECT, onConnect);
			_socket.addEventListener(IOErrorEvent.IO_ERROR, onError);
			_socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
			_socket.connect(_host, _port);
		}

		public function send( key:String, message:String, error:Error = null ):void
		{
			var command:String = formatMessage(key, message, error);
			if( _isConnected )
			{
				while( _buffer.length > 0 )
				{
					_socket.send(_buffer.shift());
				}
				_socket.send(command);
			}
			else
			{
				_buffer.push(command);
			}
		}

		protected function formatMessage( key:String, message:String, error:Error = null ):String 
		{
			var command:String;
			var showMessage:String = message;
			
			if( error != null )
			{
				showMessage += ":::";
				var stackTrace:String = error.getStackTrace();
				if( stackTrace != null && stackTrace.length > 0 )
				{
					showMessage += stackTrace + "\n ";
				}
			}
			
			if( showMessage.indexOf(":::") > -1 )
			{
				var elems:Array = showMessage.split(":::");
				var title:String = elems[0];
				var body:String = elems[1];
				command = "!SOS<showFoldMessage key=\"" + key + "\"><title><![CDATA[" + title + "]]></title><message><![CDATA[" + body + "]]></message></showFoldMessage>\n";
			}
			else 
			{
				command = "!SOS<showMessage key=\"" + key + "\"><![CDATA[" + showMessage + "]]></showMessage>\n";
			}
			return command;
		}

		private function onError( e:Event ):void
		{
			_socket.close();
			_socket = null;
			_buffer = null;
			trace("flexunit.sosui.SosConnector: Failure to connect Powerflasher SOS!");
		}

		private function onConnect( e:Event ):void
		{
			_isConnected = true;
			trace("flexunit.sosui.SosConnector: Powerflasher SOS is ready.");
		}

		private var _host:String;
		private var _port:uint;
		private var _isConnected:Boolean;
		private var _socket:XMLSocket;
		private var _buffer:Array;
	}
}
